<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务，帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\store\model\supplier;

use app\common\model\OrderCallbackLog as OrderCallbackLogModel;
use app\common\model\OrderGoods as OrderGoodsModel;
use app\store\model\Supplier as SupplierModel;
use app\common\enum\order\OrderStatus as OrderStatusEnum;
use app\common\enum\order\PayStatus as PayStatusEnum;
use app\common\enum\order\ReceiptStatus as ReceiptStatusEnum;
use app\common\enum\order\DeliveryStatus as DeliveryStatusEnum;
use app\common\library\helper;
use app\store\service\order\Export;

/**
 * 订单管理
 * Class OrderGoods
 * @package app\store\model\supplier
 */
class OrderGoods extends OrderGoodsModel
{
    // 全部订单
    const LIST_TYPE_ALL = 'all';

    // 待发货订单
    const LIST_TYPE_DELIVERY = 'delivery';

    // 待收货订单
    const LIST_TYPE_RECEIPT = 'receipt';

    // 待付款订单
    const LIST_TYPE_PAY = 'pay';

    // 已完成订单
    const LIST_TYPE_COMPLETE = 'complete';

    // 已取消
    const LIST_TYPE_CANCEL = 'cancel';

    // 已退款
    const LIST_TYPE_REFUND = 'refund';

    /**
     * 订单列表
     * @param string $dataType 订单类型
     * @param bool $export
     * @return mixed
     */
    public function getList(array $param = [], $export = false)
    {
        // 检索查询条件
        $filter   = $this->getQueryFilter($param);
        $dataType = $param['orderStatus'] ?? self::LIST_TYPE_ALL;
        // 设置订单类型条件
        if ($dataType == self::LIST_TYPE_REFUND) {//退款完成订单
            $dataTypeFilter = [
                ['r.type', 'in', [10, 30]],
                ['r.status', '=', 20]
            ];
        } else {
            $dataTypeFilter = $this->getFilterDataType($dataType);
        }
        $OrderCallbackLogModel = new OrderCallbackLogModel();
        if ($export) {
            $list              = $this->with(['image'])
                ->alias('g')
                ->leftJoin('order o', 'g.order_id = o.order_id')
                ->leftJoin('order_refund r', 'r.order_id = g.order_id and r.order_goods_id = g.order_goods_id')
                ->where($dataTypeFilter)
                ->where($filter)
                ->where('o.order_parent_id', '>', 0)
                ->where('o.is_delete', '=', 0)
                ->order(['o.create_time' => 'desc'])
                ->field('o.*,r.type,r.status,r.refund_money,g.*')
                ->select()
                ->toArray();
            $goodsList['data'] = $list;
        } else {
            $goodsList = $this->with(['image'])
                ->alias('g')
                ->leftJoin('order o', 'g.order_id = o.order_id')
                ->leftJoin('order_refund r', 'r.order_id = g.order_id and r.order_goods_id = g.order_goods_id')
                ->where($dataTypeFilter)
                ->where($filter)
                ->where('o.order_parent_id', '>', 0)
                ->where('o.is_delete', '=', 0)
                ->field('o.*,r.type,r.status,g.*')
                ->order(['o.create_time' => 'desc'])
                ->paginate(15)->toArray();

            $goodSum                       = $this->alias('g')
                ->leftJoin('order o', 'g.order_id = o.order_id')
                ->leftJoin('order_refund r', 'r.order_id = g.order_id and r.order_goods_id = g.order_goods_id')
                ->field([
                    'SUM(total_num) as total_num', //购买商品总数量
                    'FORMAT(SUM(cost_price/total_num),2) as total_cost_price', // 成本价
                    'SUM(cost_price) as total_pay_price', //总成本价
                    'SUM(refund_money) as total_refund_money', //总退款金额
                ])
                ->where($dataTypeFilter)
                ->where($filter)
                ->where('o.order_parent_id', '>', 0)
                ->where('o.is_delete', '=', 0)
                ->order(['o.create_time' => 'desc'])
                ->find()->toArray();
            $goodSum['total_refund_money'] = '退款金额：' . $goodSum['total_refund_money'];
            if (isset($param['supplierIds']) && $param['supplierIds'][0] == 10016) {//虚拟商品重庆地心科技有限公司
                $filterLog = [];
                // 起止时间
                if (isset($param['betweenTime']) && !empty($param['betweenTime'])) {
                    $times       = between_time($param['betweenTime']);
                    $filterLog[] = ['create_time', '>=', $times['start_time']];
                    $filterLog[] = ['create_time', '<', $times['end_time'] + 86400];
                }
                //订单号
                if (isset($param['orderNo']) && !empty($param['orderNo'])) {
                    $filterLog[] = ['order_no', '=', $param['orderNo']];
                }
                if (isset($param['orderStatus']) && $param['orderStatus'] == 'cancel') {//已取消的
                    $filterLog[] = ['recharge_status', '=', 4];
                } else {
                    $filterLog[] = ['recharge_status', '=', 3];
                }
                $CallbackLog                         = $OrderCallbackLogModel->where($filterLog)->field([
                    'SUM(settlement_price) as channel_settlement_price', //商家实际扣除成本
                ])->find()->toArray();
                $goodSum['channel_settlement_price'] = '重庆地心成本价：' . $CallbackLog['channel_settlement_price'];
            }
            $goodsList = array_merge($goodSum, $goodsList);
        }

        $supplierModel = new SupplierModel;
        $supplierList  = $supplierModel->getListByCategory()->toArray();//所有供应商
        $supplierList  = array_column($supplierList, 'business_name', 'supplier_id');
        if ($goodsList['data']) {
            $order_ids       = array_column($goodsList['data'], 'order_id');
            $callbackLogList = $OrderCallbackLogModel->where('order_id', 'in', $order_ids)->where('recharge_status', '>', 0)->select()->toArray();
            $callbackLogList = array_column($callbackLogList, 'settlement_price', 'order_id');
            //数据处理
            foreach ($goodsList['data'] as $key => $value) {
                if ($value['order_status'] == 20) {
                    $goodsList['data'][$key]['order_status'] = self::LIST_TYPE_CANCEL;
                } elseif ($value['order_status'] == 30) {
                    $goodsList['data'][$key]['order_status'] = self::LIST_TYPE_COMPLETE;
                } elseif ($value['delivery_status'] == 10) {
                    $goodsList['data'][$key]['order_status'] = self::LIST_TYPE_DELIVERY;
                } elseif ($value['receipt_status'] == 10) {
                    $goodsList['data'][$key]['order_status'] = self::LIST_TYPE_RECEIPT;
                }
                if ($value['type'] == 10 && $value['status'] == 20) {
                    $goodsList['data'][$key]['order_status'] = self::LIST_TYPE_REFUND;
                }
                if ($value['type'] == 30 && $value['status'] == 20) {//缺货退款
                    $goodsList['data'][$key]['order_status'] = self::LIST_TYPE_REFUND;
                }
                $supplier_name = $supplierList[$value['supplier_id']] ?? '自营';
                if (!$export) {
                    $supplier_name = helper::truncateString($supplier_name, 20);
                }

                $goodsList['data'][$key]['total_pay_price'] = $value['cost_price'];
                $goodsList['data'][$key]['cost_price']      = helper::bcdiv($value['cost_price'], $value['total_num']);
                if (isset($callbackLogList[$value['order_id']]) && $goodsList['data'][$key]['cost_price'] != $callbackLogList[$value['order_id']]) {
                    $goodsList['data'][$key]['channel_cost_price'] = $callbackLogList[$value['order_id']];
                }
                $goodsList['data'][$key]['supplier_name'] = $supplier_name;
                $goodsList['data'][$key]['pay_type']      = $this->payMethod($value['pay_cash'], $value['bd_type'], $value['deduction_value']);
            }
        }
        return $goodsList;
    }


    /**
     * 设置检索查询条件
     * @param array $param
     * @return array
     */
    private function getQueryFilter(array $param): array
    {
        // 默认参数
        $params = $this->setQueryDefaultValue($param, [
            'supplierIds' => [],     // 供应商Id
            'goodName'    => '',    // 商品名称
            'orderNo'     => '',    // 订单号
            'betweenTime' => [],    // 起止时间
            'dateType'    => '',    //7天 30天
        ]);
        // 检索查询条件
        $filter = [];
        // 供应商id
        if ($params['supplierIds']) {
            $filter[] = ['g.supplier_id', 'in', $params['supplierIds']];
        }
        //商品名称
        if (!empty($params['goodName'])) {
            $filter[] = ['g.goods_name', 'like', "%{$params['goodName']}%"];
        }
        //订单号
        if (!empty($params['orderNo'])) {
            $filter[] = ['o.order_no', '=', $params['orderNo']];
        }
        // 起止时间
        if (!empty($params['betweenTime'])) {
            $times    = between_time($params['betweenTime']);
            $filter[] = ['o.create_time', '>=', $times['start_time']];
            $filter[] = ['o.create_time', '<', $times['end_time'] + 86400];
        }
        if ($params['dateType'] == 1) {//7天
            $start_time = strtotime(date('Y-m-d 0:0:0', strtotime('-6 day')));
            $end_time   = strtotime(date('Y-m-d 23:59:59'));
            $filter[]   = ['o.create_time', '>=', $start_time];
            $filter[]   = ['o.create_time', '<', $end_time];
        }
        if ($params['dateType'] == 2) {//30天
            $start_time = strtotime(date('Y-m-d 0:0:0', strtotime('-29 day')));
            $end_time   = strtotime(date('Y-m-d 23:59:59'));
            $filter[]   = ['o.create_time', '>=', $start_time];
            $filter[]   = ['o.create_time', '<', $end_time];
        }
        return $filter;
    }

    /**
     * 设置订单类型条件
     * @param string $dataType
     * @return array
     */
    private function getFilterDataType(string $dataType = self::LIST_TYPE_ALL): array
    {
        // 数据类型
        $filter = [];
        switch ($dataType) {
            case self::LIST_TYPE_ALL:
                $filter = [];
                break;
            case self::LIST_TYPE_DELIVERY:
                $filter = [
                    ['pay_status', '=', PayStatusEnum::SUCCESS],
                    ['delivery_status', '=', DeliveryStatusEnum::NOT_DELIVERED],
                    ['order_status', 'in', [OrderStatusEnum::NORMAL, OrderStatusEnum::APPLY_CANCEL]]
                ];
                break;
            case self::LIST_TYPE_RECEIPT:
                $filter = [
                    ['pay_status', '=', PayStatusEnum::SUCCESS],
                    ['delivery_status', '=', DeliveryStatusEnum::DELIVERED],
                    ['receipt_status', '=', ReceiptStatusEnum::NOT_RECEIVED]
                ];
                break;
            case self::LIST_TYPE_PAY:
                $filter[] = ['pay_status', '=', PayStatusEnum::PENDING];
                $filter[] = ['order_status', '=', OrderStatusEnum::NORMAL];
                break;
            case self::LIST_TYPE_COMPLETE:
                $filter[] = ['order_status', '=', OrderStatusEnum::COMPLETED];
                break;
            case self::LIST_TYPE_CANCEL:
                $filter[] = ['order_status', '=', OrderStatusEnum::CANCELLED];
                break;
        }
        return $filter;
    }

    /**
     * 支付方式
     * @param $pay_money
     * @param $bd_type
     * @return string
     */
    public function payMethod($pay_money, $bd_type, $deduction_value)
    {
        // 20、微信支付 30、邦豆支付 40、微信+邦豆 50、微信+现金券 60、微信+礼金券
        if ($bd_type == 0) {//现金支付
            return '微信支付';
        }
        if ($pay_money == '0.00' && $bd_type == 7) {//帮豆支付
            return '邦豆支付';
        }
        if ($pay_money == '0.00' && $bd_type == 10) {//帮豆支付
            return '余额支付';
        }
        if ((float)$deduction_value > 0 && $bd_type == 7 && (float)$pay_money > 0) {//微信+邦豆
            return '微信+邦豆';
        }
        if ($deduction_value > 0 && $bd_type == 6 && $pay_money > 0) {//微信+现金券
            return '微信+现金券';
        }
        if ($deduction_value > 0 && $bd_type == 5 && $pay_money > 0) {//微信+礼金券
            return '微信+礼金券';
        }
        if ($deduction_value > 0 && $bd_type == 10 && $pay_money > 0) {//微信+余额
            return '微信+余额';
        }
        return '异常';
    }

    /**
     * 订单列表导出
     * @param array $param
     * @return mixed
     */
    public function goodsListExport($param)
    {
        $goodsList = $this->getList($param, true);
        if (empty($goodsList['data'])) {
            $this->error = '导出的数据不能为空';
            return false;
        }
        $export  = new Export();
        $cvsData = [];
        foreach ($goodsList['data'] as $key => $item) {
            $specs = '';
            if ($item['goods_props']) {
                $specs = implode(',', array_column(array_column($item['goods_props'], 'value'), 'name'));
            }
            $cvsData[$key]['transaction_id']    = $export->filterValue($item['transaction_id']);
            $cvsData[$key]['order_no']          = $export->filterValue($item['order_no']);
            $cvsData[$key]['order_time']        = $item['create_time'];
            $cvsData[$key]['goods_name']        = $item['goods_name'] . $specs;//商品名称
            $cvsData[$key]['total_num']         = $item['total_num'];//商品数量
            $cvsData[$key]['goods_price']       = $item['goods_price'];//单价
            $cvsData[$key]['goods_total_price'] = helper::bcmul($item['goods_price'], $item['total_num']);//总销售额
            $cvsData[$key]['pay_cash']          = $item['pay_cash'];//微信支付
            $cvsData[$key]['deduction_value']   = $item['deduction_value'];//三券抵扣
            $item['channel_cost_price'] = isset($item['channel_cost_price']) ? $item['channel_cost_price'] : 0;
            $cvsData[$key]['cost_price']        = $item['channel_cost_price'] > 0 ? $item['channel_cost_price'] : $item['cost_price'];//成本价
            //$cvsData[$key]['total_pay_price']    = $item['total_pay_price'];//总成本价
            $cvsData[$key]['total_pay_price'] = $item['channel_cost_price'] > 0 ? helper::bcmul($item['channel_cost_price'], $item['total_num']) : $item['total_pay_price'];//总成本价
            $cvsData[$key]['pay_type']        = $item['pay_type'];//支付方式
            //$cvsData[$key]['order_status']    = $item['order_status'];//订单状态
            $cvsData[$key]['supplier_name'] = $item['supplier_name'];//供应商
            if ($item['order_status'] == 'delivery') {
                $cvsData[$key]['order_status'] = '待发货';
            } elseif ($item['order_status'] == 'receipt') {
                $cvsData[$key]['order_status'] = '待收货';
            } elseif ($item['order_status'] == 'complete') {
                $cvsData[$key]['order_status'] = '已完成';
            } elseif ($item['order_status'] == 'cancel') {
                $cvsData[$key]['order_status'] = '已取消';
            }
            if ($item['type'] == 10 && $item['status'] == 20) {
                $cvsData[$key]['order_status']    = '已退款';
                $cvsData[$key]['deduction_value'] = helper::bcsub($item['deduction_value'], $item['refund_money']);//三券抵扣
            }

            if ($item['type'] == 30 && $item['status'] == 20) {
                $cvsData[$key]['order_status']    = '缺货已退款';
                $cvsData[$key]['deduction_value'] = 0;//三券抵扣
            }
            //$cvsData[$key]['settlement_type']      = $item['settlement_type'] == 1 ? '不分成' : ($item['settlement_type'] == 2 ? '初级分成' : ($item['settlement_type'] == 3 ? '高级分成' : ($item['settlement_type'] == 4 ? '中级分成' : '')));
        }
        $columns = ['交易号', '订单号', '下单时间', '商品名称', '商品数量', '单价', '总销售额', '微信', '三券', '成本价', '总成本价', '支付方式', '供应商', '订单状态'];
        // 输出并写入到excel文件
        $filePath = $export->outputExcel($columns, $cvsData);
        return base_url() . $filePath;
    }
}
